// VBConversions Note: VB project level imports
using System.Data;
using DevExpress.XtraEditors.Controls;
using System.Diagnostics;
using System.Xml.Linq;
using DevExpress.XtraEditors.Repository;
using System.Collections.Generic;
using System.Data.SqlClient;
using Microsoft.VisualBasic;
using System.Configuration;
using System.Collections;
using DevExpress.XtraEditors;
using System.Data.Sql;
using Microsoft.SqlServer;
using System.Windows.Forms;
using System;
using DevExpress.XtraReports;
using Microsoft.SqlServer.Management.Smo;
using DevExpress;
using System.Linq;
using System.IO;
// End of VB project level imports


/// <summary>
/// This class is use to read data from a Metaquery, it also represent the Command Screen
/// So we can access easily the informations
/// Ex. Metaqueries, MetaColumns...
/// </summary>
/// <remarks></remarks>
namespace SCIEF.SysBFW.CommonExt
{
	[Serializable()]public class MetaQuery : IDisposable
	{
#region  FIELD
		private string _sqlStatement;
		private string _recordVersionField;
		private DataTable _metaColumns = new DataTable();
		private DataTable _metaParams = new DataTable();
		
		private List<MetaQuery> _childQueries; // VBConversions Note: Initial value of "new List<MetaQuery>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		private Dictionary<string, string> _metaColumnCaption; // VBConversions Note: Initial value of "new Dictionary<string, string>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		
		private MetaQuery metaCUDCommand = null;
		
		private Dictionary<string, Guid> _listOfLov; // VBConversions Note: Initial value of "new Dictionary<string, Guid>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		private Dictionary<string, Guid> _listOfLookup; // VBConversions Note: Initial value of "new Dictionary<string, Guid>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		
		private Dictionary<string, Guid> _listOfVisibleLov; // VBConversions Note: Initial value of "new Dictionary<string, Guid>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		private Dictionary<string, Guid> _listOfVisibleLookup; // VBConversions Note: Initial value of "new Dictionary<string, Guid>()" cannot be assigned here since it is non-static.  Assignment has been moved to the class constructors.
		
#endregion
		
#region  Events
		
		public delegate void BeforeSqlEventHandler(MetaQuery mq, System.ComponentModel.CancelEventArgs e);
		private BeforeSqlEventHandler BeforeSqlEvent;
		
		public event BeforeSqlEventHandler BeforeSql
		{
			add
			{
				BeforeSqlEvent = (BeforeSqlEventHandler) System.Delegate.Combine(BeforeSqlEvent, value);
			}
			remove
			{
				BeforeSqlEvent = (BeforeSqlEventHandler) System.Delegate.Remove(BeforeSqlEvent, value);
			}
		}
		
		//Public Event OnBeforeSQL As System.ComponentModel.CancelEventHandler
#endregion
		
#region  Property
		public string MetaQuerieCD {get; set;}
		private Guid _MetaControlID = Guid.Empty; //André aime pas ça quand y a pas de valeur , BD
		public Guid MetaControlID
		{
			get
			{
				return _MetaControlID;
			}
			set
			{
				_MetaControlID = value;
			}
		}
		private bool _AllowCreate = true; //set to true to continue all Possiblity with Preview MetaCommand , BD
		public bool AllowCreate
		{
			get
			{
				return _AllowCreate;
			}
			set
			{
				_AllowCreate = value;
			}
		}
		private bool _AllowRead = true; //set to true to continue all Possiblity with Preview MetaCommand ,BD
		public bool AllowRead
		{
			get
			{
				return _AllowRead;
			}
			set
			{
				_AllowRead = value;
			}
		}
		private bool _AllowUpdate = true; //set to true to continue all Possiblity with Preview MetaCommand ,BD
		public bool AllowUpdate
		{
			get
			{
				return _AllowUpdate;
			}
			set
			{
				_AllowUpdate = value;
			}
		}
		private bool _AllowDelete = true; //set to true to continue all Possiblity with Preview MetaCommand ,BD
		public bool AllowDelete
		{
			get
			{
				return _AllowDelete;
			}
			set
			{
				_AllowDelete = value;
			}
		}
		public string ApplicationName {get; set;}
		public string Caption {get; set;} //André dit que par Default STRING c'est empty , mais ça l'évarve , BD
		public Guid? CaptionId {get; set;}
		
		public Guid? CommandCategoryID {get; set;}

        private Guid? _CommandClassID = null;
		public Guid? CommandClassID
		{
			get
			{
				return _CommandClassID;
			}
			set
			{
				_CommandClassID = value;
			}
		}
		private Guid _CommandGroupID = Guid.Empty;
		public Guid CommandGroupID
		{
			get
			{
				return _CommandGroupID;
			}
			set
			{
				_CommandGroupID = value;
			}
		}
		private Guid _CommandTypeID = Guid.Empty;
		public Guid CommandTypeID
		{
			get
			{
				return _CommandTypeID;
			}
			set
			{
				_CommandTypeID = value;
			}
		}
		public Dictionary<string, object> DefaultParentValue {get; set;}
		private Guid _ParentID = Guid.Empty;
		public Guid ParentID
		{
			get
			{
				return _ParentID;
			}
			set
			{
				_ParentID = value;
			}
		}
		public Guid QueryID {get; set;}
		public int RelationOrder {get; set;}
		public string PKColumn_Name {get; set;}
		public string FKColumn_Name {get; set;}
		private Guid _TipId = Guid.Empty;
		public Guid TipId
		{
			get
			{
				return _TipId;
			}
			set
			{
				_TipId = value;
			}
		}
		public string GUIDField {get; set;}
		public string QueryName {get; set;}
		public string SQLFrom {get; set;}
		public string SQLGroupBy {get; set;}
		public string SQLHaving {get; set;}
		public string SQLOrderBy {get; set;}
		public string SQLSelect {get; set;}
		private DataTable _ResultQuery = null;
		public DataTable ResultQuery
		{
			get
			{
				return _ResultQuery;
			}
			set
			{
				_ResultQuery = value;
			}
		}
		public string SQLWhere {get; set;}
		public string SQLWhereContext {get; set;}
		public string ToolTip {get; set;}
		public string UniqueTable {get; set;}
		
		/// <summary>
		/// Shortcut to test if we have Lookup to proceed by the consumer (Ex.: ExtendedGrid)
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public bool HasLookup
		{
			get
			{
				return _listOfLookup.Count > 0;
			}
		}
		/// <summary>
		/// Shortcut to test if we have LOV to proceed by the consumer (Ex.: ExtendedGrid)
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public bool HasLov
		{
			get
			{
				return _listOfLov.Count> 0;
			}
		}
		/// <summary>
		/// Lookup list that will be process by the main consumer
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public Dictionary<string, Guid> ListOfLookup
		{
			get
			{
				return _listOfLookup;
			}
		}
		/// <summary>
		/// Lookup list that will be process by the main consumer
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public Dictionary<string, Guid> ListOfVisibleLookup
		{
			get
			{
				return _listOfVisibleLookup;
			}
		}
		
		/// <summary>
		/// LOV list that will be process by the main consumer
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public Dictionary<string, Guid> ListOfLov
		{
			get
			{
				return _listOfLov;
			}
		}
		/// <summary>
		/// LOV list that will be process by the main consumer
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public Dictionary<string, Guid> ListOfVisibleLov
		{
			get
			{
				return _listOfVisibleLov;
			}
		}
		
		/// <summary>
		/// Collection of child Query
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks></remarks>
		public List<MetaQuery> ChildQueries
		{
			get
			{
				if (_childQueries.Count == 0)
				{
					this.FillChildQuery();
				}
				return _childQueries;
			}
			set
			{
				_childQueries = value;
			}
		}
		public Dictionary<string, string> MetaColumnCaption
		{
			get
			{
				return _metaColumnCaption;
			}
		}
		/// <summary>
		/// All the column from the select statement
		///
		/// By design we initialise the metacolumns if it's not fill. MetaDataTable access this property.
		/// For backward compatibility we automaticly Fill it.
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks>For caching purpose we can assign the property</remarks>
		public DataTable MetaColumns
		{
			get
			{
				if (_metaColumns.Rows.Count == 0)
				{
					FillMetaColumns();
				}
				return _metaColumns;
			}
			set
			{
				_metaColumns = value;
			}
		}
		
		public DataTable MetaParams
		{
			get
			{
				if (_metaParams.Rows.Count == 0)
				{
					FillMetaParams();
				}
				return _metaParams;
			}
			set
			{
				_metaParams = value;
			}
		}
		/// <summary>
		/// Witch field to be use for Version, default = TStamp
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks>TODO: Remove when all table will be base on RecordVersion, not TStamp </remarks>
		public string RecordVersionField
		{
			get
			{
				if (string.IsNullOrEmpty(_recordVersionField))
				{
					if (this.SQLStatement.Contains("RecordVersion"))
					{
						_recordVersionField = "RecordVersion";
					}
					else
					{
						_recordVersionField = "TStamp";
					}
				}
				return _recordVersionField;
			}
			set
			{
				_recordVersionField = value;
			}
		}
		
		/// <summary>
		/// Contain the result of the SQLStatement
		/// </summary>
		/// <value></value>
		/// <returns></returns>
		/// <remarks>For caching purpose we can assign the property</remarks>
		
		public string SQLStatement
		{
			get
			{
				if (string.IsNullOrEmpty(_sqlStatement))
				{
					System.Text.StringBuilder with_1 = new System.Text.StringBuilder();
					if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT)
					{
						with_1.Append("SELECT ");
					}
					
					with_1.Append(this.SQLSelect);
					
					if (this.SQLFrom != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("FROM ");
						with_1.Append(this.SQLFrom);
					}
					
					if (this.SQLWhere != string.Empty || this.SQLWhereContext != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("WHERE ");
						with_1.Append(this.SQLWhere);
						
						//Extra condition to apply from a specific context. ex.: parameter set from a form
						//An other WHERE from another MetaCommand
						if (this.SQLWhereContext != string.Empty)
						{
							if (with_1.Length > 0)
							{
								with_1.Append(" ");
							}
							if (this.SQLWhere != string.Empty)
							{
								with_1.Append(" AND ");
							}
							with_1.Append(this.SQLWhereContext);
						}
					}
					
					if (this.SQLGroupBy != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("GROUP BY ");
						with_1.Append(this.SQLGroupBy);
					}
					
					if (this.SQLHaving != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("HAVING ");
						with_1.Append(this.SQLHaving);
					}
					if (this.SQLOrderBy != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("ORDER BY ");
						with_1.Append(this.SQLOrderBy);
					}
					_sqlStatement = with_1.ToString();
				}
				return _sqlStatement;
			}
			set
			{
				_sqlStatement = value;
			}
		}
		
		/// <summary>
		/// Return a SQL Statement, that can be use in a Sub Select.
		/// Created for PLBase so we can have Where clause also propagate to child Query
		/// </summary>
		/// <returns></returns>
		/// <remarks></remarks>
		public string SQLStatementParsed
		{
			get
			{
				if (string.IsNullOrEmpty(_sqlStatement))
				{
					System.Text.StringBuilder with_1 = new System.Text.StringBuilder();
					if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT)
					{
						with_1.Append("SELECT " + "\r\n");
					}
					
					with_1.Append(this.SQLSelect + "\r\n");
					
					if (this.SQLFrom != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("FROM " + "\r\n");
						with_1.Append(this.SQLFrom + "\r\n");
					}
					
					if (this.SQLWhere != string.Empty || this.SQLWhereContext != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("WHERE " + "\r\n");
						with_1.Append(this.SQLWhere + "\r\n");
						
						//Extra condition to apply from a specific context. ex.: parameter set from a form
						//An other WHERE from another MetaCommand
						if (this.SQLWhereContext != string.Empty)
						{
							if (with_1.Length > 0)
							{
								with_1.Append(" ");
							}
							if (this.SQLWhere != string.Empty)
							{
								with_1.Append(" AND ");
							}
							with_1.Append(this.SQLWhereContext + "\r\n");
						}
					}
					
					if (this.SQLGroupBy != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("GROUP BY " + "\r\n");
						with_1.Append(this.SQLGroupBy + "\r\n");
					}
					
					if (this.SQLHaving != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("HAVING " + "\r\n");
						with_1.Append(this.SQLHaving + "\r\n");
					}
					if (this.SQLOrderBy != string.Empty)
					{
						if (with_1.Length > 0)
						{
							with_1.Append(" ");
						}
						with_1.Append("ORDER BY " + "\r\n");
						with_1.Append(this.SQLOrderBy + "\r\n");
					}
					_sqlStatement = with_1.ToString();
				}
				return _sqlStatement;
			}
			set
			{
				_sqlStatement = value;
			}
		}
		
		
#endregion
		
#region  Methode
		
		public string GetSQLForSubSelect(string fields)
		{
			string sql = default(string);
			
			System.Text.StringBuilder with_1 = new System.Text.StringBuilder();
			if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT)
			{
				with_1.Append("SELECT " + "\r\n");
			}
			
			with_1.Append(fields + "\r\n");
			
			if (this.SQLFrom != string.Empty)
			{
				if (with_1.Length > 0)
				{
					with_1.Append(" ");
				}
				with_1.Append("FROM " + "\r\n");
				with_1.Append(this.SQLFrom + "\r\n");
			}
			
			if (this.SQLWhere != string.Empty || this.SQLWhereContext != string.Empty)
			{
				if (with_1.Length > 0)
				{
					with_1.Append(" ");
				}
				with_1.Append("WHERE " + "\r\n");
				with_1.Append(this.SQLWhere + "\r\n");
				
				//Extra condition to apply from a specific context. ex.: parameter set from a form
				//An other WHERE from another MetaCommand
				if (this.SQLWhereContext != string.Empty)
				{
					if (with_1.Length > 0)
					{
						with_1.Append(" ");
					}
					if (this.SQLWhere != string.Empty)
					{
						with_1.Append(" AND ");
					}
					with_1.Append(this.SQLWhereContext + "\r\n");
				}
			}
			
			if (this.SQLGroupBy != string.Empty)
			{
				if (with_1.Length > 0)
				{
					with_1.Append(" ");
				}
				with_1.Append("GROUP BY " + "\r\n");
				with_1.Append(this.SQLGroupBy + "\r\n");
			}
			
			if (this.SQLHaving != string.Empty)
			{
				if (with_1.Length > 0)
				{
					with_1.Append(" ");
				}
				with_1.Append("HAVING " + "\r\n");
				with_1.Append(this.SQLHaving + "\r\n");
			}
			sql = with_1.ToString();
			return sql;
		}
		
		
		
		public MetaQuery()
		{
			ResultQuery = new DataTable();
		}
		
		
		/// <summary>
		///  Return a DataTable with Schema info of the SQL Statement
		/// </summary>
		/// <remarks>Call from Generate Columns (Value) </remarks>
		public DataTable GetSQLSchemaInfo()
		{
			SqlCommand command = Base.Connection.Command();
			SqlDataReader reader = null;
			DataTable dataTbl = null;
			string tmpWhere = default(string);
			try
			{
				
				tmpWhere = this.SQLWhere;
				this.SQLWhere = string.Empty;
				_sqlStatement = null;
				command.CommandText = this.SQLStatement;
				this.SQLWhere = tmpWhere;
				_sqlStatement = null;
				//
				if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SP)
				{
					command.CommandType = CommandType.StoredProcedure;
				}
				//Pour des raison de performance on demande le CommandBehavior.SchemaOnly.
				//BUGBUG: Si une SP a plusieurs commande ca ne fonctionne pas. il faut faire le ExecuteReader seulement.
				reader = command.ExecuteReader(CommandBehavior.SchemaOnly);
				//reader = command.ExecuteReader()
				dataTbl = reader.GetSchemaTable();
				return dataTbl;
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.GetSchemaInfo()(){0}{1}{0}{0}Queryname: {2}", "\r\n", this.SQLStatement, this.QueryName)));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				if (command.Connection.State == ConnectionState.Open)
				{
					command.Connection.Close();
					command.Connection.Dispose();
				}
				command.Dispose();
				command = null;
			}
		}
		/// <summary>
		///  Return a DataTable with Schema info of the SQL Parameters of the SP
		/// </summary>
		/// <remarks></remarks>
		public DataTable GetSPSchemaInfo()
		{
			DataTable dataTbl = null;
			DataRow dataRow = null;
			
			using (SqlCommand sqlcommand = MetaQuery.GetSPCmdByMetaName(this.QueryName))
			{
				if (sqlcommand != null)
				{
					dataTbl = new DataTable("SchemaTable");
					dataTbl.Columns.Add("ColumnName");
					dataTbl.Columns.Add("DataTypeName");
					dataTbl.Columns.Add("DataType");
					foreach (SqlParameter param in sqlcommand.Parameters)
					{
						dataRow = dataTbl.NewRow();
						dataRow["ColumnName"] = param.ParameterName;
						dataRow["DataTypeName"] = param.SqlDbType.ToString();
						dataRow["DataType"] = Base.IdRepository.SqlDbTypeToType[param.SqlDbType].ToString();
						dataTbl.Rows.Add(dataRow);
					}
				}
			}
			
			return dataTbl;
		}
		
		public SqlCommand InitQueryParams()
		{
			SqlCommand sqlcmd = Base.Connection.Command();
			sqlcmd.CommandText = this.SQLStatement;
			if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SP)
			{
				sqlcmd.CommandType = CommandType.StoredProcedure;
			}
			
			SqlParameter param = default(SqlParameter);
			foreach (DataRow row in this.MetaParams.Rows)
			{
				param = new SqlParameter(row["ColumnName"].ToString(), Base.IdRepository.GUIDToSqlDbType[((Guid) (row["pDataTypeID_FK"]))]);
				sqlcmd.Parameters.Add(param);
			}
			return sqlcmd;
		}
		/// <summary>
		///  Fill a DataTable from the query
		/// </summary>
		/// <param name="CommandBehavior"></param>
		/// <param name="sqlCmd"> Use to execute an SP With Parameters already set by the caller (Ex: ReportBuilder or Pivot Table)</param>
		/// <remarks></remarks>
		///
		public void FillResultQuery(CommandBehavior CommandBehavior = System.Data.CommandBehavior.Default, SqlCommand sqlCmd = null)
		{
			SqlCommand command = Base.Connection.Command();
			SqlDataReader reader = null;
			try
			{
				this.ResultQuery.Clear();
				this.ResultQuery.TableName = this.QueryName;
				OnBeforeSql(this);
				//
				if (this.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SP)
				{
					if (sqlCmd != null)
					{
						command = sqlCmd.Clone();
						sqlCmd.Dispose();
					}
					command.CommandType = CommandType.StoredProcedure;
				}
				command.CommandText = this.SQLStatement;
				reader = command.ExecuteReader(CommandBehavior);
				//
				//begin load does not validate all the integrity of the table. (help for speed)
				//it's ok here cause we are loading from the DB.
				this.ResultQuery.BeginLoadData();
				this.ResultQuery.Load(reader);
				this.ResultQuery.EndLoadData();
			}
			catch (Exception ex)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.FillResultQuery(){0}{1}{0}{0}Queryname: {2}", "\r\n", this.SQLStatement, this.QueryName), ex));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				if (command.Connection.State == ConnectionState.Open)
				{
					command.Connection.Close();
					command.Connection.Dispose();
				}
				command.Dispose();
				command = null;
			}
		}
		/// <summary>
		/// Use when you need to call a specific UPDATE/DELETE or INSERT statement
		/// Use the ExecuteNonQuery of the SqlCommand
		/// </summary>
		/// <remarks></remarks>
		public int ExecuteQuery()
		{
			SqlCommand command = Base.Connection.Command();
			try
			{
				command.CommandText = this.SQLStatement;
				return command.ExecuteNonQuery();
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.ExecuteQuery(){0}{1}{0}{0}Queryname: {2}", "\r\n", this.SQLStatement, this.QueryName)));
			}
			finally
			{
				command.Connection.Close();
				command.Connection.Dispose();
				command.Dispose();
				command = null;
			}
		}
		
		
		
		
		/// <summary>
		/// Give the possibility to modify the Metaquery before the SQL is executed
		/// </summary>
		/// <param name="mq"></param>
		/// <remarks></remarks>
		public void OnBeforeSql(MetaQuery mq)
		{
			System.ComponentModel.CancelEventArgs e = new System.ComponentModel.CancelEventArgs(false);
			if (BeforeSqlEvent != null)
				BeforeSqlEvent(mq, e);
			if (!e.Cancel)
			{
				this.CopyTo(mq);
			}
		}
		/// <summary>
		/// Copy the properties of the current instance to the one pass in parameter
		/// </summary>
		/// <param name="mq">MetaQuery that receive the properties</param>
		/// <remarks></remarks>
		public void CopyTo(MetaQuery mq)
		{
			mq.QueryID = this.QueryID;
			mq.ApplicationName = this.ApplicationName;
			mq.QueryName = this.QueryName;
			mq.ParentID = this.ParentID;
			mq.UniqueTable = this.UniqueTable;
			mq.GUIDField = this.GUIDField;
			//
			mq.CommandCategoryID = this.CommandCategoryID;
			mq.CommandClassID = this.CommandClassID;
			mq.CommandGroupID = this.CommandGroupID;
			mq.CommandTypeID = this.CommandTypeID;
			//
			mq.SQLSelect = this.SQLSelect;
			mq.SQLFrom = this.SQLFrom;
			mq.SQLWhere = this.SQLWhere;
			mq.SQLWhereContext = this.SQLWhereContext;
			mq.SQLOrderBy = this.SQLOrderBy;
			mq.SQLGroupBy = this.SQLGroupBy;
			mq.SQLHaving = this.SQLHaving;
			
			mq.RelationOrder = this.RelationOrder;
			mq.PKColumn_Name = this.PKColumn_Name;
			mq.FKColumn_Name = this.FKColumn_Name;
			mq.CaptionId = this.CaptionId;
			mq.TipId = this.TipId;
			mq.Caption = this.Caption;
			mq.ToolTip = this.ToolTip;
			mq.MetaQuerieCD = this.MetaQuerieCD;
			mq.MetaControlID = this.MetaControlID;
			mq.AllowCreate = this.AllowCreate;
			mq.AllowRead = this.AllowRead;
			mq.AllowUpdate = this.AllowUpdate;
			
		}
#endregion
		
#region  Function
		public static DataRow GetDataById(string queryName, Guid id)
		{
			DataRow aRow = null;
			using (MetaQuery aMq = MetaQuery.GetMetaQueryByName(queryName))
			{
				aMq.SQLWhere = string.Format("{0} = \'{1}\'", aMq.GUIDField, id.ToString());
				aMq.FillResultQuery();
				if (aMq.ResultQuery.Rows.Count > 0)
				{
					aRow = aMq.ResultQuery.Rows[0];
				}
				return aRow;
			}
			
		}
		/// <summary>
		/// Build a Store Proc SQLCommand Base On a MetaQuery - Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables
		/// </summary>
		/// <param name="queryName"></param>
		/// <param name="applicationName"></param>
		/// <returns></returns>
		/// <remarks>Make Sure Your StoreProc Parameters Match The Column Name Of Your Tables</remarks>
		public static SqlCommand GetSPCmdByMetaName(string queryName, string applicationName = null)
		{
			MetaQuery mq = default(MetaQuery);
			mq = MetaQuery.GetMetaQueryByName(queryName, applicationName);
			if (mq == null)
			{
				throw (new Exception(string.Format("Invalid MetaCommand: MetaQuery.GetSPCmdByName(){0}{1}", "\r\n", queryName)));
			}
			return MetaQuery.GetSPCmdByMeta(mq);
		}
		
		private static MetaQuery GetSSPMetaQuery(Guid? queryId = null, string queryName = "", string applicationName = null)
		{
			MetaQuery mq = default(MetaQuery);
			System.Data.SqlClient.SqlCommand command = CommonExt.Base.Connection.Command();
			SqlDataReader reader = null;
			try
			{
				command.CommandText = "ssp_MetaQuery";
				command.CommandType = CommandType.StoredProcedure;
				
				command.Parameters.AddWithValue("@QueryID", queryId);
				command.Parameters.AddWithValue("@QueryName", queryName);
				command.Parameters.AddWithValue("@ApplicationName", applicationName);
				
				//Ne pas utiliser Base.AppManager.ApplicationOption.LanguageId ca creer une boucle infinie,
				//GetSSPMetaQuery est la fonction du framework SCIEF la plus appeler,
				//ApplicationOption en a besoin pour déterminer le language de l'usager
				//command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId)
				//
				command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.LanguageId);
				//
				reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				mq = GetMetaQueryProperties(reader);
				return mq;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				command.Dispose();
				command = null;
			}
		}
		
		public static MetaQuery GetMetaQueryByControlID(Guid controlID)
		{
			MetaQuery mq = default(MetaQuery);
			System.Data.SqlClient.SqlCommand command = CommonExt.Base.Connection.Command();
			SqlDataReader reader = null;
			try
			{
				command.CommandText = "ssp_MetaQueryByControlID";
				command.CommandType = CommandType.StoredProcedure;
				
				command.Parameters.AddWithValue("@ControlID", controlID);
				command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.LanguageId);
				//
				reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				mq = GetMetaQueryProperties(reader);
				return mq;
			}
			catch (Exception)
			{
				throw;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				command.Dispose();
				command = null;
			}
		}
		/// <summary>
		/// Build an SQLCommand for StoredProc. and prepare the parameters
		/// </summary>
		/// <param name="mq">MetaQuery</param>
		/// <param name="trimAt">When you need your SqlParameter.SourceColumn with no @ </param>
		/// <returns>SqlCommand</returns>
		/// <remarks></remarks>
		public static SqlCommand GetSPCmdByMeta(MetaQuery mq, bool trimAt = true)
		{
			//J'ai mis les constanats ici pour pouvoir garder ma Fonction Shared. aleblanc
			//Const METALIST_METACOMMANDTYPE_SP As String = "{8A6E0E00-F8C6-4B23-B75D-D4352242DC43}"
			//Dim valueSP = New Guid(METALIST_METACOMMANDTYPE_SP)
			//
			SqlCommand command = null;
			if (mq.CommandTypeID == Base.IdRepository.METALIST_METACOMMANDTYPE_SP)
			{
				command = Base.Connection.Command();
				command.CommandText = mq.SQLSelect; //C'est une SP pas besoin de passer par mq.SQLStatement
				command.CommandType = CommandType.StoredProcedure;
				//On va chercher les paramêtres de la SP
				SqlCommandBuilder.DeriveParameters(command);
				
				//We check trimAt first, so we dont evaluate in each iteration of the For Each.
				if (trimAt == true)
				{
					foreach (SqlParameter param in command.Parameters)
					{
						//Convention a suivre. Parametername = Colonne
						param.SourceColumn = param.ParameterName.TrimStart('@');
						param.SourceVersion = DataRowVersion.Current;
					}
				}
				else
				{
					foreach (SqlParameter param in command.Parameters)
					{
						//Convention a suivre. Parametername = Colonne
						param.SourceColumn = param.ParameterName;
						param.SourceVersion = DataRowVersion.Current;
					}
				}
				
			}
			else
			{
				throw (new Exception(string.Format("Not Define has SP: MetaQuery.GetSPCmdByName(){0}{1}", "\r\n", mq.QueryName)));
			}
			return command;
		}
		
		/// <summary>
		/// Get the MetaCommand by Guid
		/// </summary>
		/// <param name="guid"></param>
		/// <returns>Return Nothing when query is not found</returns>
		/// <remarks>Guid are unique by definition, no need to pass the application name</remarks>
		public static MetaQuery GetMetaQueryById(Guid guid)
		{
			return MetaQuery.GetSSPMetaQuery(guid);
		}
		/// <summary>
		/// Get the MetaCommand by Name
		/// </summary>
		/// <param name="queryName"></param>
		/// <param name="applicationName"></param>
		/// <returns>Return Nothing when query is not found</returns>
		/// <remarks></remarks>
		public static MetaQuery GetMetaQueryByName(string queryName, string applicationName = null)
		{
			return MetaQuery.GetSSPMetaQuery(null, queryName, applicationName);
		}
		
		public static MetaQuery GetMetaQueryProperties(SqlDataReader reader)
		{
			MetaQuery query = new MetaQuery();
			
			if (reader.Read())
			{
				//Pk always there
				query.QueryID = new Guid(reader["QueryID"].ToString());
				//
				query.ApplicationName = reader["ApplicationName"].ToString();
				query.GUIDField = reader["GUIDField"].ToString();
				query.QueryName = reader["QueryName"].ToString();
				query.SQLFrom = reader["SQLFrom"].ToString();
				query.SQLGroupBy = reader["SQLGroupBy"].ToString();
				query.SQLHaving = reader["SQLHaving"].ToString();
				query.SQLOrderBy = reader["SQLOrderBy"].ToString();
				query.SQLSelect = reader["SQLSelect"].ToString();
				query.SQLWhere = reader["SQLWhere"].ToString();
				query.UniqueTable = reader["UniqueTable"].ToString();
				//null allow
				if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["CommandTypeID_FK"])))
				{
					query.CommandTypeID = new Guid(reader["CommandTypeID_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["CommandCategoryID_FK"])))
				{
					query.CommandCategoryID = new Guid(reader["CommandCategoryID_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["CommandClassID_FK"])))
				{
					query.CommandClassID = new Guid(reader["CommandClassID_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["CommandGroupID_FK"])))
				{
					query.CommandGroupID = new Guid(reader["CommandGroupID_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["ParentID_FK"])))
				{
					query.ParentID = new Guid(reader["ParentID_FK"].ToString());
				}

                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["CaptionId_FK"])))
				{
					query.CaptionId = new Guid(reader["CaptionId_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["TipId_FK"])))
				{
					query.TipId = new Guid(reader["TipId_FK"].ToString());
				}
                if (!(Microsoft.VisualBasic.Information.IsDBNull(reader["RelationOrder"])))
				{
					query.RelationOrder = System.Convert.ToInt32(reader["RelationOrder"]);
				}
				query.PKColumn_Name = reader["PKColumn_Name"].ToString();
				query.FKColumn_Name = reader["FKColumn_Name"].ToString();
				query.MetaQuerieCD = reader["MetaQuerieCD"].ToString();
				query.AllowCreate = System.Convert.ToBoolean(reader["AllowCreate"]);
				query.AllowRead = System.Convert.ToBoolean(reader["AllowRead"]);
				query.AllowUpdate = System.Convert.ToBoolean(reader["AllowUpdate"]);
				query.ToolTip = reader["pToolTip"].ToString();
				query.Caption = reader["pCaption"].ToString();
				
			}
			else
			{
				query = null;
			}
			return query;
		}
		/// <summary>
		/// Go get the DataRow from a query base on the parameter.
		/// SELECT * FROM "tableName" WHERE "guidFieldName" = "id"
		/// </summary>
		/// <param name="tableName"></param>
		/// <param name="guidFieldName"></param>
		/// <param name="id"></param>
		/// <returns></returns>
		/// <remarks></remarks>
		public static DataRow FetchRow(string tableName, string guidFieldName, Guid id)
		{
			SqlCommand command = Base.Connection.Command();
			SqlDataReader reader = null;
			DataTable dtrow = new DataTable();
			DataRow dr = null;
			try
			{
				command.CommandText = string.Format("SELECT * FROM {0} WHERE {1} = \'{2}\'", tableName, guidFieldName, id.ToString());
				reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				if (reader.HasRows)
				{
					dtrow.Load(reader);
					dr = dtrow.Rows[0];
				}
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.FetchRow{0} {1}", "\r\n", command.CommandText)));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				dtrow.Dispose();
				command.Dispose();
				dtrow = null;
				command = null;
			}
			return dr;
		}
		//
		public DataRow RefetchRow(Guid id)
		{
			SqlCommand command = Base.Connection.Command();
			SqlDataReader reader = null;
			DataTable dtrow = new DataTable();
			DataRow dr = null;
			try
			{
				command.CommandText = this.SQLRefetchRow(id);
				reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				if (reader.HasRows)
				{
					dtrow.Load(reader);
					dr = dtrow.Rows[0];
				}
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.RefetchDataRow{0}{1}", "\r\n", command.CommandText)));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				command.Dispose();
				command = null;
				dtrow.Dispose();
				dtrow = null;
			}
			return dr;
		}
		/// <summary>
		///  Refetch the RowVersion
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		/// <remarks>Base on the function SQLRefetchRowVersion</remarks>
		public byte[] RefetchRowVersion(Guid id)
		{
			SqlCommand command = Base.Connection.Command();
			SqlDataReader reader = null;
			byte[] recordVersion = null;
			try
			{
				command.CommandText = this.SQLRefetchRowVersion(id);
				reader = command.ExecuteReader(CommandBehavior.CloseConnection);
				if (reader.Read())
				{
					if (!(Microsoft.VisualBasic.Information.IsDBNull(reader[this.RecordVersionField])))
					{
						recordVersion = (byte[]) (reader[this.RecordVersionField]);
					}
				}
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.RefetchRowVersion{0}{1}", "\r\n", command.CommandText)));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				command.Dispose();
				command = null;
			}
			return recordVersion;
		}
		/// <summary>
		/// Go Get the MetaQuery for CUD
		/// </summary>
		/// <returns></returns>
		/// <remarks>Base on ParentId and Classe = CUD </remarks>
		public MetaQuery GetMetaCUDCommand()
		{
			SqlCommand sqlcmd = null;
			MetaQuery mq = default(MetaQuery);
			SqlDataReader reader = null;
			try
			{
				sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaQuery");
				sqlcmd.Parameters["@ParentID_FK"].Value = this.QueryID;
				sqlcmd.Parameters["@CommandClassID_FK"].Value = Base.IdRepository.METALIST_METACOMMANDCLAS_CUD;
				reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);
				mq = GetMetaQueryProperties(reader);
				return mq;
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				sqlcmd.Dispose();
				sqlcmd = null;
			}
		}
		/// <summary>
		/// SQL query to return the row version
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		/// <remarks>The ID is the one define in the GUIDField, make sure it's guid field</remarks>
		private string SQLRefetchRowVersion(Guid id)
		{
			return string.Format("SELECT {0} FROM {1} WHERE {2} = \'{3}\'", this.RecordVersionField, this.UniqueTable, this.GUIDField, id.ToString());
		}
		/// <summary>
		/// SQL query to return the row
		/// </summary>
		/// <param name="id"></param>
		/// <returns></returns>
		/// <remarks>The ID is the one define in the GUIDField, make sure it's guid field</remarks>
		private string SQLRefetchRow(Guid id)
		{
			System.Text.StringBuilder with_1 = new System.Text.StringBuilder();
			if (this.CommandTypeID != Base.IdRepository.METALIST_METACOMMANDTYPE_SELECT)
			{
				with_1.Append("SELECT ");
			}
			with_1.Append(this.SQLSelect);
			if (this.SQLFrom != string.Empty)
			{
				if (with_1.Length > 0)
				{
					with_1.Append(" ");
				}
				with_1.Append("FROM ");
				with_1.Append(this.SQLFrom);
			}
			if (with_1.Length > 0)
			{
				with_1.Append(" ");
			}
			with_1.Append("WHERE ");
			if (this.SQLWhere != string.Empty)
			{
				with_1.Append(this.SQLWhere);
				with_1.Append(" AND ");
			}
			with_1.Append(string.Format("{0}.{1} = \'{{{2}}}\'", this.UniqueTable, this.GUIDField, id));
			return with_1.ToString();
		}
		/// <summary>
		/// Va chercher les requêtes enfants pour le CUD.
		/// La Metalist Classe, les MetaListValues.ListOrder doivent etre 0=Read et 1=CUD
		/// Les autres ordre sont moint important....
		/// </summary>
		/// <remarks></remarks>
		public void FillChildQuery()
		{
			
			DataTable childQueriesDtb = new DataTable();
			MetaQuery mq = new MetaQuery();
			System.Data.SqlClient.SqlCommand sqlcmd = null;
			SqlDataReader reader = null;
			try
			{
				sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaQueryChild");
				sqlcmd.Parameters["@QueryID"].Value = this.QueryID;
				reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);
				childQueriesDtb.BeginLoadData();
				childQueriesDtb.Load(reader);
				childQueriesDtb.EndLoadData();
				//Load The Collection
				foreach (DataRow dr in childQueriesDtb.Rows)
				{
					mq = MetaQuery.GetMetaQueryById((Guid) (dr["QueryID"]));
					this._childQueries.Add(mq);
				}
			}
			catch (Exception)
			{
				throw (new Exception(string.Format("Invalid SQL command: MetaQuery.FillChildQuery(){0}{1}", "\r\n", this.SQLStatement)));
			}
			finally
			{
				if (reader != null)
				{
					reader.Close();
					reader = null;
				}
				if (sqlcmd != null)
				{
					sqlcmd.Dispose();
					sqlcmd = null;
				}
				mq.Dispose();
				childQueriesDtb.Dispose();
			}
		}
		/// <summary>
		/// Ici on va chercher toute les requetes d'affichage pour batir le DataSet
		/// (Toute les requêtes, enfants)
		/// </summary>
		/// <returns></returns>
		/// <remarks>Retourne le DataTable avec les champs suivants:
		///          {MetaqueryLevel},{ParentRelation},{Relation},{ParentQueryName},{CommandCategory},{QueryName}, _
		///          {PKColumn_Name},{FKColumn_Name},{ParentId_FK},{ParentGUIDField},{GUIDField},{RelationOrder},{ControlID_FK}
		/// </remarks>
		public DataTable GetChildDisplayQuery()
		{
			//this function will get the hierarchie of metaqueries
			DataTable _dataTable = new DataTable();
			System.Data.SqlClient.SqlCommand sqlcmd = MetaQuery.GetSPCmdByMetaName("SSPMetaQueryChildDisplay");
			SqlDataReader reader = null;
			
			sqlcmd.Parameters["@QueryName"].Value = QueryName;
			reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection);
			_dataTable.BeginInit();
			_dataTable.BeginLoadData();
			_dataTable.Load(reader);
			_dataTable.EndLoadData();
			_dataTable.EndInit();
			reader.Close();
			sqlcmd.Dispose();
			reader = null;
			sqlcmd = null;
			return _dataTable;
			
		}
		
		/// <summary>
		/// Get the Metacolumns associate to the Metaquery
		/// </summary>
		/// <remarks></remarks>
		public void FillMetaColumns()
		{
			
			SqlCommand command = CommonExt.Base.Connection.Command();
			SqlDataReader reader = null;
			try
			{
				if (this.QueryName != string.Empty)
				{
					command.CommandText = "ssp_PrepareGrid";
					command.CommandType = CommandType.StoredProcedure;
					command.Parameters.AddWithValue("@QueryName", QueryName);
					command.Parameters.AddWithValue("@UserID_FK", Base.AppManager.UserID);
					command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId);
					command.Parameters.AddWithValue("@ColumnGroupID_FK", Base.IdRepository.METALIST_METACOLUMNGROUPE_VALUE);
					
					reader = command.ExecuteReader(CommandBehavior.CloseConnection);
					this._metaColumns.Clear();
					this._metaColumns.BeginLoadData();
					this._metaColumns.Load(reader);
					this._metaColumns.EndLoadData();
				}
				else
				{
					throw (new Exception("QueryName is empty: MetaQuery.FillMetaColumns()"));
				}
			}
			catch (Exception ex)
			{
				throw (ex);
			}
			finally
			{
				reader.Close();
				reader = null;
				if (command != null)
				{
					command.Dispose();
					command = null;
				}
			}
		}
		/// <summary>
		///  Get the Parameter use gor the metaquery
		/// </summary>
		/// <remarks></remarks>
		public void FillMetaParams()
		{
			SqlCommand command = CommonExt.Base.Connection.Command();
			SqlDataReader reader = null;
			try
			{
				if (this.QueryName != string.Empty)
				{
					command.CommandText = "ssp_PrepareGrid";
					command.CommandType = CommandType.StoredProcedure;
					command.Parameters.AddWithValue("@QueryName", QueryName);
					command.Parameters.AddWithValue("@UserID_FK", Base.AppManager.UserID);
					command.Parameters.AddWithValue("@LanguageStringID_FK", Base.AppManager.ApplicationOption.LanguageId);
					command.Parameters.AddWithValue("@ColumnGroupID_FK", Base.IdRepository.METALIST_METACOLUMNGROUPE_PARAMETER);
					
					reader = command.ExecuteReader(CommandBehavior.CloseConnection);
					this._metaParams.Clear();
					this._metaParams.BeginLoadData();
					this._metaParams.Load(reader);
					this._metaParams.EndLoadData();
				}
				else
				{
					throw (new Exception("QueryName is empty: MetaQuery.FillMetaParams()"));
				}
			}
			catch (Exception ex)
			{
				throw (ex);
			}
			finally
			{
				reader.Close();
				reader = null;
				if (command != null)
				{
					command.Dispose();
					command = null;
				}
			}
		}
		
		/// <summary>
		/// Get Metacolumns LOV's
		/// </summary>
		/// <remarks></remarks>
		public void GetLOV_LKP()
		{
			bool colVisible = default(bool);
			string colName = default(string);
			foreach (DataRow row in this.MetaColumns.Rows)
			{
				colVisible = (System.Convert.ToInt32(row["pVisible"]) == 0) ? false : true;
				colName = (string) (row["ColumnName"].ToString());
				//
				if (!row.IsNull("TranslateQueryID_FK"))
				{
					Guid gid = new Guid(row["TranslateQueryID_FK"].ToString());
					this.AddToListOfLookup(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLookup.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLookup.Add(colName, gid);
						}
					}
					//Here we check for LOV when No TR/Lookup are available - 2012-11-07
				}
				else if (!row.IsNull("LOVQueryID_FK"))
				{
					Guid gid = new Guid(row["LOVQueryID_FK"].ToString());
					this.AddToListOfLookup(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLookup.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLookup.Add(colName, gid);
						}
					}
				}
				//
				if (!row.IsNull("LOVQueryID_FK"))
				{
					Guid gid = new Guid(row["LOVQueryID_FK"].ToString());
					this.AddToListOfLov(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLov.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLov.Add(colName, gid);
						}
					}
				}
				
			}
		}
		
		/// <summary>
		/// Get Metacolumns Params LOV's
		/// </summary>
		/// <remarks></remarks>
		public void GetParamsLOV_LKP()
		{
			bool colVisible = default(bool);
			string colName = default(string);
			foreach (DataRow row in this.MetaParams.Rows)
			{
				colVisible = (System.Convert.ToInt32(row["pVisible"]) == 0) ? false : true;
				colName = (string) (row["ColumnName"].ToString());
				//
				if (!row.IsNull("TranslateQueryID_FK"))
				{
					Guid gid = new Guid(row["TranslateQueryID_FK"].ToString());
					this.AddToListOfLookup(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLookup.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLookup.Add(colName, gid);
						}
					}
				}
				else if (!row.IsNull("LOVQueryID_FK"))
				{
					Guid gid = new Guid(row["LOVQueryID_FK"].ToString());
					this.AddToListOfLookup(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLookup.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLookup.Add(colName, gid);
						}
					}
				}
				//
				if (!row.IsNull("LOVQueryID_FK"))
				{
					Guid gid = new Guid(row["LOVQueryID_FK"].ToString());
					this.AddToListOfLov(colName, gid);
					if (colVisible)
					{
						if (!_listOfVisibleLov.ContainsKey(colName)) // Exception occur, if add twice the same key, because it's a sorted type
						{
							this._listOfVisibleLov.Add(colName, gid);
						}
					}
				}
				
			}
		}
		/// <summary>
		/// Populate our list of lookup to be use by the consumer
		/// </summary>
		/// <param name="keyColumn"></param>
		/// <param name="qryID"></param>
		/// <remarks></remarks>
		public void AddToListOfLookup(string keyColumn, Guid qryID)
		{
			if (!this._listOfLookup.ContainsKey(keyColumn)) // Exception occur, if add twice the same key, because it's a sorted type
			{
				this._listOfLookup.Add(keyColumn, qryID);
			}
		}
		/// <summary>
		/// Populate our list of LOV to be use by the consumer
		/// </summary>
		/// <param name="keyColumn"></param>
		/// <param name="qryID"></param>
		/// <remarks></remarks>
		public void AddToListOfLov(string keyColumn, Guid qryID)
		{
			if (!this._listOfLov.ContainsKey(keyColumn)) // Exception occur, if add twice the same key
			{
				this._listOfLov.Add(keyColumn, qryID);
			}
		}
		
		/// <summary>
		/// Convenient for debuging purpose
		/// </summary>
		/// <returns>QueryName is return</returns>
		/// <remarks>Instead of the type, we will see the QueryName in Watch Window</remarks>
		public override string ToString()
		{
			return QueryName;
		}
#endregion
#region  IDisposable Support
		// IDisposable
		private bool disposedValue = false; // To detect redundant calls
		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposedValue)
			{
				if (disposing)
				{
					// TODO: free other state (managed objects).
					this.ResultQuery.Dispose();
					this.ResultQuery = null;
					this._childQueries = null;
					this.DefaultParentValue = null;
					this.metaCUDCommand = null;
					this._metaColumnCaption = null;
					this._metaColumns = null;
					this._listOfLookup = null;
					this._listOfLov = null;
					this._listOfVisibleLookup = null;
					this._listOfVisibleLov = null;
				}
				// TODO: free your own state (unmanaged objects).
				// TODO: set large fields to null.
			}
			this.disposedValue = true;
		}
		
		// This code added by Visual Basic to correctly implement the disposable pattern.
		public void Dispose()
		{
			// Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
			Dispose(true);
			GC.SuppressFinalize(this);
		}
#endregion
		
		private void MetaQuery_BeforeSql(MetaQuery mq, System.ComponentModel.CancelEventArgs e)
		{
			
		}
	}
	
	
}
